// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//

#include <kmsql/postgre/parser.h>
#include <kmsql/postgre/functions.h>
#include <kmsql/postgre/parser/parser.h>
#include <kmsql/postgre/parser/scansup.h>
#include <kmsql/postgre/common/keywords.h>

namespace kmsql::pg {

PostgresParser::PostgresParser() : success(false), parse_tree(nullptr), error_message(""), error_location(0) {}

void PostgresParser::Parse(const std::string &query) {
	pg_parser_init();
	parse_result res;
	pg_parser_parse(query.c_str(), &res);
	success = res.success;

	if (success) {
		parse_tree = res.parse_tree;
	} else {
		error_message = std::string(res.error_message);
		error_location = res.error_location;
	}
}

std::vector<PGSimplifiedToken> PostgresParser::Tokenize(const std::string &query) {
	pg_parser_init();
	auto tokens = tokenize(query.c_str());
	pg_parser_cleanup();
	return std::move(tokens);
}

PostgresParser::~PostgresParser()  {
    pg_parser_cleanup();
}

PGKeywordCategory PostgresParser::IsKeyword(const std::string &text) {
	return is_keyword(text.c_str());
}

std::vector<PGKeyword> PostgresParser::KeywordList() {
	// FIXME: because of this, we might need to change the libpg_query library to use tokudb::vector
	std::vector<PGKeyword> tmp(keyword_list());
	return tmp;
}

void PostgresParser::SetPreserveIdentifierCase(bool preserve) {
	set_preserve_identifier_case(preserve);
}

}
